﻿/*苏兴迎 E-Mail:284238436@qq.com*/
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace MVC
{
    public class Controller
    {
        public HttpListenerRequest Request = null;
        public HttpListenerResponse Response = null;
        public HttpSession Session = null;
        public Hashtable Params = new Hashtable();
        private string content = "";
        private string view = "";
        private FileItem fileitem = null;
        private string url_suffix = "";
        private Compress compress = null;
        public static Hashtable pageCacheList = new Hashtable();
        public Controller()
        {
            fileitem = new FileItem();
        }
        public void Init(HttpListenerContext context, HttpSession Session_, string view_, string url_suffix_, Compress compress_)
        {
            url_suffix = url_suffix_;
            compress = compress_;
            view = view_;
            Session = Session_;
            Request = context.Request;
            Response = context.Response;
            Create();
        }
        public virtual void Create()
        {

        }
        /// <summary>
        /// 判断是否POST方法
        /// </summary>
        /// <returns></returns>
        public bool isPOST()
        {
            return Request.HttpMethod.ToUpper().Equals("POST");
        }
        /// <summary>
        /// 判断是否GET方法
        /// </summary>
        /// <returns></returns>
        public bool isGET()
        {
            return Request.HttpMethod.ToUpper().Equals("GET");
        }
        /// <summary>
        /// 判断是否Put方法
        /// </summary>
        /// <returns></returns>
        public bool isPut()
        {
            return Request.HttpMethod.ToUpper().Equals("PUT");
        }
        /// <summary>
        /// 判断是否Any方法
        /// </summary>
        /// <returns></returns>
        public bool isAny()
        {
            return Request.HttpMethod.ToUpper().Equals("ANY");
        }
        /// <summary>
        /// 判断是否Delete方法
        /// </summary>
        /// <returns></returns>
        public bool isDelete()
        {
            return Request.HttpMethod.ToUpper().Equals("DELETE");
        }
        /// <summary>
        /// 判断是否Head方法
        /// </summary>
        /// <returns></returns>
        public bool isHead()
        {
            return Request.HttpMethod.ToUpper().Equals("HEAD");
        }
        /// <summary>
        /// 判断是否Patch方法
        /// </summary>
        /// <returns></returns>
        public bool isPatch()
        {
            return Request.HttpMethod.ToUpper().Equals("PATCH");
        }
        /// <summary>
        /// 获取RESTFull风格参数
        /// </summary>
        /// <param name="index">参数下标</param>
        /// <returns></returns>
        public string InputById(int index)
        {
            string[] ss = url_suffix.Split('/');
            if (ss.Length > 1 && index < ss.Length && index > 0)
                return ss[index];
            else

                return "";
        }
        /// <summary>
        /// 获取请求参数
        /// </summary>
        /// <param name="key">参数名</param>
        /// <returns></returns>
        public string Input(string key)
        {
            if (Request.HttpMethod.Equals("GET"))
                return Get(key);
            else
            {
                return Form(key);
            }
        }
        /// <summary>
        /// 如果请求的参数为JSON数组，将数据转换为JSON数组对象
        /// </summary>
        /// <returns>JArray</returns>
        public JArray InputToArray()
        {
            JArray jsonArray = new JArray();
            string txt = Body();
            if (txt.Length > 0 && txt.Substring(0, 1) == "[" && txt.Substring(txt.Length - 1) == "]")
            {
                jsonArray = JArray.Parse(txt);
            }
            return jsonArray;
        }
        /// <summary>
        /// 获取请求参数转换为json对象
        /// </summary>
        /// <returns>JObjct</returns>
        public JObject InputToMap()
        {
            JObject res = new JObject();

            string txt = Body();
            if (txt.Length > 0 && txt.Substring(0, 1) == "[" && txt.Substring(txt.Length - 1) == "]")
            {
                return res;
            }
            else if (txt.Length > 0 && txt.Substring(0, 1) == "{" && txt.Substring(txt.Length - 1) == "}")
            {
                res = JObject.Parse(txt);
            }
            else
            {
                if (txt.Length > 0)
                {
                    string[] txttmp = txt.Split('&');
                    foreach (string s in txttmp)
                    {
                        if (!string.IsNullOrEmpty(s))
                        {
                            string[] tmp = s.Split('=');
                            if (!string.IsNullOrEmpty(tmp[1]))
                                res[tmp[0]] = Uri.UnescapeDataString(tmp[1]);
                            else
                                res[tmp[0]] = "";
                        }
                    }
                }
                foreach (string key in Request.QueryString.Keys)
                {
                    res[key] = Request.QueryString.Get(key);

                }
            }

            return res;
        }
        /// <summary>
        /// 请求内容
        /// </summary>
        /// <returns></returns>
        public string Body()
        {
            if (string.IsNullOrEmpty(content))
            {

                if (Request.InputStream.CanRead)
                {

                    int len = (int)Request.ContentLength64;
                    byte[] sdata = new byte[len];

                    try
                    {
                        int k = 0, kk = 0;
                        while (kk < len)
                        {

                            k = Request.InputStream.Read(sdata, kk, len - kk);
                            kk = kk + k;
                        }
                        content = Encoding.UTF8.GetString(sdata);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Content方法：" + e.Message);
                    }

                }




            }

            return content;
        }
        /// <summary>
        /// 获取上传文件
        /// </summary>
        /// <returns></returns>
        public FileItem Files()
        {
            string type = Request.ContentType.ToString();
            string s = Request.TransportContext.ToString();
            int k = type.IndexOf("multipart/form-data");
            if (fileitem.FileName == null && k >= 0)
            {
                int len = (int)Request.ContentLength64;
                byte[] sdata = new byte[len];
                byte[] tmp = new byte[1024];
                int kk1 = 0, kk2 = 0;

                while (true)
                {
                    kk1 = Request.InputStream.Read(tmp, 0, tmp.Length);
                    if (kk1 > 0)
                    {
                        Array.Copy(tmp, 0, sdata, kk2, kk1);
                        kk2 = kk2 + kk1;
                    }
                    else
                    {
                        break;
                    }
                }

                if (len > 512)
                {
                    tmp = new byte[512];
                }
                else
                {
                    tmp = new byte[len];
                }
                Array.Copy(sdata, tmp, tmp.Length);
                string content = Encoding.UTF8.GetString(tmp);
                if (fileitem.FileName == null)
                {
                    string[] ss = content.Split('\n');
                    int leng = 0;
                    int hleng = Encoding.UTF8.GetBytes(ss[0].Trim() + "--").Length + 4;

                    for (int i = 0; i < ss.Length; i++)
                    {
                        string s1 = ss[i].ToString().Replace('\r', ' ').Trim();
                        if (s1.IndexOf("form-data") >= 0)
                        {
                            string[] tmps = s1.Split(';');
                            fileitem.FileName = tmps[2].Split('=')[1].Replace('\"', ' ').Trim();
                        }
                        leng += Encoding.UTF8.GetBytes(s1).Length + 2;
                        if (s1.Trim().Equals(""))
                        {
                            fileitem.FileStream = new byte[sdata.Length - leng - hleng];
                            Array.Copy(sdata, leng, fileitem.FileStream, 0, fileitem.FileStream.Length);

                            break;
                        }

                    }
                }

            }

            return fileitem;
        }
        /// <summary>
        /// 获取GET方法提交参数
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string Get(string key)
        {
            string value = Request.QueryString.Get(key);
            if (!string.IsNullOrEmpty(value))
                value = Encoding.GetEncoding(Config.document_charset).GetString(Request.ContentEncoding.GetBytes(value));
            return value;

        }
        /// <summary>
        /// 接收Post方法提交参数
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string Form(string key)
        {
            string value = "";

            string type = Request.ContentType;
            if (!string.IsNullOrEmpty(type))
            {
                int k = type.IndexOf("application/x-www-form-urlencoded");
                if (k >= 0)
                {
                    if (content.Equals(""))
                    {
                        content = Body();
                    }
                    string[] ps = content.Split('&');
                    foreach (string item in ps)
                    {
                        if (!string.IsNullOrEmpty(item))
                        {
                            string[] ps2 = item.Split('=');
                            if (ps2[0].Equals(key))
                            {
                                value = ps2[1];
                                if (!string.IsNullOrEmpty(value))
                                    value = Uri.UnescapeDataString(value);
                                break;
                            }
                        }

                    }
                }
            }

            return value;
        }
        /// <summary>
        /// HTML中传递数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void SetAttr(string key, object value)
        {
            if (Params.ContainsKey(key))
                Params[key] = value;
            else
                Params.Add(key, value);
        }
        /// <summary>
        /// 输出html页面
        /// </summary>
        /// <param name="htmlName"></param>
        public void Show(string htmlName)
        {
            try
            {
                Response.StatusCode = 200;
                string root = "";
                string html = "";
                if (!view.Equals(""))
                {
                    view += "/";
                }
                if (!Config.WebRoot.Equals(""))
                {
                    root = Config.WebRoot + "/";
                }
                htmlName = htmlName + Config.template_type;
                string htmlfile = root + Config.template + "/" + view + htmlName;

                if (pageCacheList.ContainsKey(htmlfile))
                {
                    html = pageCacheList[htmlfile].ToString();
                    Response.ContentType = "text/html; charset=" + Config.document_charset;
                    HTMLParser htmlparser = new HTMLParser(Params);
                    htmlparser.path = view;
                    string tmp = htmlparser.parser(html.ToString());
                    Write(html.ToString());
                }
                else
                {
                    if (File.Exists(htmlfile))
                    {
                        html = File.ReadAllText(htmlfile);
                        HTMLParser htmlparser = new HTMLParser(Params);
                        htmlparser.path = view;
                        string tmp = htmlparser.parser(html);
                        html = tmp;
                        if (!Config.open_debug)
                        {
                            lock (pageCacheList.SyncRoot)
                            {
                                pageCacheList.Add(htmlfile, html);
                            }
                        }

                        Response.ContentType = "text/html; charset=" + Config.document_charset;
                        Write(html.ToString());
                    }
                    else
                    {
                        Error404(htmlName);
                    }

                }
            }
            catch (Exception e)
            {

                Console.Out.WriteLine(e.Message);
                Error404(htmlName);
            }


        }
        private void Error404(string url)
        {
            string s = "";
            Response.StatusCode = 404;
            Response.ContentType = "text/html; charset=" + Config.document_charset;
            s = "<html><body><div style=\"text-align: left;\">";
            s = s + "<div><h1> 404 </h1></div>";
            s = s + "<hr><div>[ " + url + " ] Page Not Find  </div></div></body></html>";
            if (!Config.Error404.Equals(""))
            {
                string htmlfile = Config.Error404;
                if (File.Exists(htmlfile))
                {
                    s = File.ReadAllText(htmlfile);
                }
            }
            Write(s);
        }
        public void ShowStream(byte[] bytes, string ContentType= "image/jpeg")
        {
            Response.StatusCode = 200;
            Response.ContentType = ContentType + "; charset=" + Config.document_charset;
            WriteByte(bytes);
        }
        /// <summary>
        /// 输出JSON字符串
        /// </summary>
        /// <param name="json">文本</param>
        public void ShowJSON(string json)
        {
            Response.StatusCode = 200;
            Response.ContentType = "application/json; charset=" + Config.document_charset;
            if (Config.Cross_Origin.AllowOrigin != null)
            {
                Response.AddHeader("Access-Control-Allow-Credentials", Config.Cross_Origin.AllowCredentials.ToString());
                Response.AddHeader("Access-Control-Allow-Origin", Config.Cross_Origin.AllowOrigin);
                if (Config.Cross_Origin.AllowHeaders != null)
                    Response.AddHeader("Access-Control-Allow-Headers", Config.Cross_Origin.AllowHeaders);
                if (Config.Cross_Origin.AllowMethod != null)
                    Response.AddHeader("Access-Control-Allow-Method", Config.Cross_Origin.AllowMethod);

            }
            if (Config.JsonToLower)
            {
                var rx = new Regex(@"""(?<v>(\w)*?)"":", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
                var match = rx.Match(json);
                while (match.Success)
                {
                    var originalKeyName = match.Result("${v}");
                    var currentKeyName = originalKeyName.ToString().ToLower();
                    json = rx.Replace(json, "\"" + currentKeyName + "\":", 1, match.Index);
                    match = match.NextMatch();
                }
            }



            Write(json);
        }
        /// <summary>
        /// 输出JSON字符串
        /// </summary>
        /// <param name="value">对象</param>
        public void ShowJSON(object value)
        {
            string json = "";
            try
            {
                if (value == null)
                    value = "";
                json = JsonConvert.SerializeObject(value, new Newtonsoft.Json.JsonSerializerSettings()
                {
                    StringEscapeHandling = Newtonsoft.Json.StringEscapeHandling.EscapeNonAscii,
                    DateFormatString = "yyyy-MM-dd HH:mm:ss"
                });
                Response.StatusCode = 200;
                Response.ContentType = "application/json; charset=" + Config.document_charset;
            }
            catch (Exception e)
            {

                Console.Out.WriteLine(e.Message);
            }

            ShowJSON(json);
        }
        /// <summary>
        /// 输出文本
        /// </summary>
        /// <param name="text"></param>
        public void ShowText(string text)
        {
            Response.StatusCode = 200;
            Response.ContentType = "text/html; charset=" + Config.document_charset;
            Write(text);
        }
        private void Write(string content)
        {
            try
            {

                if (content == null)
                {
                    content = "";
                }
                byte[] buffer = Encoding.UTF8.GetBytes(content);
                byte[] sdata = null;
                if (compress.CompressType.ToLower().Equals("deflate"))
                {
                    sdata = compress.DeflateCompress(buffer);
                    Response.AddHeader("Content-Encoding", "deflate");
                }
                else if (compress.CompressType.ToLower().Equals("gzip"))
                {
                    Response.AddHeader("Content-Encoding", "gzip");
                    sdata = compress.GZipCompress(buffer);
                }
                else
                {
                    sdata = buffer;
                }
                Response.ContentEncoding = Encoding.UTF8;
                WriteByte(sdata);
            }
            catch (Exception e)
            {

                Log.Print(e.Message);
            }
        }
        private void WriteByte(byte[] buffer)
        {
            if (Response.OutputStream.CanWrite)
            {
                Response.ContentLength64 = buffer.Length;
                Response.OutputStream.Write(buffer, 0, buffer.Length);
                Response.OutputStream.Close();
                Response.Close();
            }
        }
        public void Success(int code = 0, string message = "操作成功")
        {
            JObject jo = new JObject();
            jo["code"] = code;
            jo["message"] = message;
            ShowJSON(jo);
        }
        public void Fail(int code = -1, string message = "操作失败")
        {
            JObject jo = new JObject();
            jo["code"] = code;
            jo["message"] = message;
            ShowJSON(jo);
        }
        public void Redirect(string url)
        {
            Response.StatusCode = 301;
            Response.RedirectLocation = url;
            Write("");
        }
        public byte[] getVCode(out string vcode, int code = 4)
        {
            string tmpcode = CreateRandomCode(4);
            vcode = tmpcode;
            byte[] jpg = CreateValidateGraphic(tmpcode);
            return jpg;
        }
        /// <summary>
        /// 生成随机的字符串
        /// </summary>
        /// <param name="codeCount"></param>
        /// <returns></returns>
        private string CreateRandomCode(int codeCount)
        {
            string allChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,a,b,c,d,e,f,g,h,i,g,k,l,m,n,o,p,q,r,F,G,H,I,G,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,s,t,u,v,w,x,y,z";
            string[] allCharArray = allChar.Split(',');
            string randomCode = "";
            int temp = -1;
            Random rand = new Random();
            for (int i = 0; i < codeCount; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
                }
                int t = rand.Next(35);
                if (temp == t)
                {
                    return CreateRandomCode(codeCount);
                }
                temp = t;
                randomCode += allCharArray[t];
            }
            return randomCode;
        }

        /// <summary>
        /// 创建验证码图片
        /// </summary>
        /// <param name="validateCode"></param>
        /// <returns></returns>
        private byte[] CreateValidateGraphic(string validateCode)
        {
            Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 16.0), 27);
            Graphics g = Graphics.FromImage(image);
            try
            {
                //生成随机生成器
                Random random = new Random();
                //清空图片背景色
                g.Clear(Color.White);
                //画图片的干扰线
                for (int i = 0; i < 25; i++)
                {
                    int x1 = random.Next(image.Width);
                    int x2 = random.Next(image.Width);
                    int y1 = random.Next(image.Height);
                    int y2 = random.Next(image.Height);
                    g.DrawLine(new Pen(Color.Silver), x1, x2, y1, y2);
                }
                Font font = new Font("Arial", 13, (FontStyle.Bold | FontStyle.Italic));
                LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true);
                g.DrawString(validateCode, font, brush, 3, 2);

                //画图片的前景干扰线
                for (int i = 0; i < 100; i++)
                {
                    int x = random.Next(image.Width);
                    int y = random.Next(image.Height);
                    image.SetPixel(x, y, Color.FromArgb(random.Next()));
                }
                //画图片的边框线
                g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);

                //保存图片数据
                MemoryStream stream = new MemoryStream();
                image.Save(stream, ImageFormat.Jpeg);

                //输出图片流
                return stream.ToArray();
            }
            finally
            {
                g.Dispose();
                image.Dispose();
            }
        }
    }
}
